﻿using System;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExcelRefresh.Logging
{
    public enum RefreshLogEntryType
    {
        FileOpened,
        FileSaved,
        ErrorFileLocked,
        ErrorPowerPivotConnect,
        ErrorPowerPivotProcess,
        ErrorDataConnection,
        ErrorPivotTableRefresh,
        ErrorOnSave
    }

    public abstract class RefreshListenerService
    {
        public abstract RefreshListener CreateListener(string filePath);
    }

    public abstract class RefreshListener
    {
        protected readonly string FilePath;
        protected readonly DateTime StartTime;
        protected TimeSpan Duration { get { return DateTime.Now - StartTime; } }

        protected RefreshListener(string filePath)
        {
            FilePath = filePath;
            StartTime = DateTime.Now;
        }

        protected abstract void Log(RefreshLogEntryType logType, string message);

        public void FileOpened()
        {
            Log(RefreshLogEntryType.FileOpened, string.Empty);
        }

        public void FileSaved()
        {
            Log(RefreshLogEntryType.FileSaved, string.Empty);
        }

        public void ErrorFileLocked()
        {
            Log(RefreshLogEntryType.ErrorFileLocked, string.Empty);
        }

        public void ErrorPowerPivotConnect(string message)
        {
            Log(RefreshLogEntryType.ErrorPowerPivotConnect, message);
        }

        public void ErrorPowerPivotProcess(string message)
        {
            Log(RefreshLogEntryType.ErrorPowerPivotProcess, message);
        }

        public void ErrorDataConnection(string message)
        {
            Log(RefreshLogEntryType.ErrorDataConnection, message);
        }

        public void ErrorPivotTableRefresh(string message)
        {
            Log(RefreshLogEntryType.ErrorPivotTableRefresh, message);
        }

        public void ErrorOnSave(string message)
        {
            Log(RefreshLogEntryType.ErrorOnSave, string.Empty);
        }

    }

    public class SqlLogRefreshListenerService : RefreshListenerService
    {
        protected readonly string ConnectionString;
        protected readonly string InsertFormatString;

        public SqlLogRefreshListenerService(string connectionString, string insertFormatString)
        {
            ConnectionString = connectionString;
            InsertFormatString = insertFormatString;
        }

        public override RefreshListener CreateListener(string filePath)
        {
            return new SqlLogRefreshListener(filePath, ConnectionString, InsertFormatString);
        }

        public class SqlLogRefreshListener : RefreshListener
        {
            protected readonly string ConnectionString;
            protected readonly string InsertFormatString;

            public SqlLogRefreshListener(string filePath,
                                        string connectionString,
                                        string insertFormatString) 
                : base(filePath)
            {
                ConnectionString = connectionString;
                InsertFormatString = insertFormatString;
            }


            protected override void Log(RefreshLogEntryType logType, string message)
            {
                try
                {
                    string statement = string.Format(
                        InsertFormatString,
                        FilePath,
                        logType,
                        message,
                        StartTime,
                        Duration);

                    using (var con = new SqlConnection(ConnectionString))
                    {
                        con.Open();
                        using (var cmd = con.CreateCommand())
                        {
                            cmd.CommandText = statement;
                            cmd.CommandType = System.Data.CommandType.Text;
                            cmd.ExecuteNonQuery();
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
        }

    }

}
